Skip to content

fix(standards): check matrix node versions - #181

Merged
twistedmelonman merged 3 commits into
mainfrom
claude/fix-node-floor-matrix
Oct 2, 2026
Merged

twistedmelonman merged 3 commits into
mainfrom
claude/fix-node-floor-matrix

Conversation

@twistedmelonman

Copy link
Copy Markdown
Member

The false OK

standards/check-node-floor.sh skipped every node-version: expression with a notice. That included ${{ matrix.node-version }}, so a job that pins Node through its strategy matrix was never checked.

nightowlstudiollc/tensegrity is the live case. Its .github/workflows/ci.yml has strategy.matrix.node-version: [18.x] and passes node-version: ${{ matrix.node-version }} to setup-node. The floor check reported it as passing while CI runs Node 18.

What changes

A ${{ matrix.<key> }} value is now resolved against the same job's literal strategy.matrix, and every value it can take is checked against the floor. The reader handles:

  • flow lists ([18.x, 22.x]), including lists that wrap across lines
  • block lists, indented or indentless
  • include: entries, in dash and continuation form
  • a matrix declared before or after the steps that use it
  • per-job scoping, so one job's matrix does not leak into another

It is an indentation-based reader written in awk, not a YAML parser. No new dependency: awk was already on every runner. A failed scan now exits 2 with an error instead of reading as "no pins".

What now fails: any job whose setup-node node-version reads a matrix key that lists a major below node_floor. Against the current tensegrity workflow:

::error::.github/workflows/ci.yml: node-version: ${{ matrix.node-version }} -> 18.x: Node 18 is below the supported floor (22)

Remaining gaps (unchanged behavior: notice, not failure)

  • A matrix, a matrix key, or an include: built from an expression (fromJSON(...)) still cannot be resolved.
  • ${{ matrix.<key> }} where the job has no literal values for that key.
  • Any other expression (${{ inputs.node }}, ${{ matrix.node || '22' }}).
  • exclude: is ignored. An excluded combination is still checked, so this can be stricter than reality, never looser.
  • A matrix node-version key that no step reads is not checked as a pin by itself.
  • Flow-mapping include items (- {node: 18}) are not read.

Release order

Moving the standards-check-v1 tag to include this will turn tensegrity's standards check red until its own matrix PR lands. That PR should merge first. This PR does not move any tag.

Testing

  • bash tests/run-tests.sh: 3 test files, 0 failed. test-check-node-floor.sh grows from 9 to 26 cases. The new matrix cases failed before the fix (6 of the first 12 went red as expected).
  • The node-floor suite passes under BSD awk, gawk, and gawk --posix. mawk (the Ubuntu default awk) was not available locally.
  • shellcheck -S info is clean on both changed files.
  • bash standards/run-standards.sh --repo .: all enabled linters clean.

Advances smartwatermelon/dev-env#78

Claude Code Bot added 3 commits October 2, 2026 10:09
check-node-floor.sh skipped every node-version expression with a
notice, including `${{ matrix.node-version }}`. A job pinned to Node 18
through its strategy matrix therefore passed the floor check: a false
OK (nightowlstudiollc/tensegrity, matrix node-version: [18.x]).

A `${{ matrix.<key> }}` value is now resolved against the same job's
literal strategy.matrix: flow lists, block lists, scalars, and include
entries (dash and continuation forms). Each value is checked against
the floor. The matrix may be declared before or after the steps.

Unchanged: a matrix or matrix value built from an expression (fromJSON)
and any non-matrix expression still produce a notice, not a failure.
exclude: is ignored, so an excluded combination is still checked.
A node-version key inside a matrix is no longer read as a pin by
itself; only the values a step reads through the matrix are checked.
The reader is indentation-based, not a YAML parser, and reads each
workflow twice.

Advances smartwatermelon/dev-env#78
Both commit-time reviewers found two gaps in the matrix reader.

A sequence written at the same indent as its key (indentless style,
`node:` then `- 18`) was dropped, so a Node 18 matrix or include entry
could still pass. Such items are now read in list and include mode.

The workflow scan ran inside a process substitution, so an awk failure
read as zero pins and a clean pass. The output is now captured first,
and a failed scan exits 2 with an error.

Advances smartwatermelon/dev-env#78
The pre-push full-diff review found that a flow list wrapped across
lines (`node: [22,` then `18]`) was read only up to the first line
break, so a below-floor entry on a later line passed with no notice.

Continuation lines are now joined until the closing bracket. A list
that never closes inside the matrix gives a notice instead of a
partial read.

Advances smartwatermelon/dev-env#78
@twistedmelonman
twistedmelonman merged commit 28efbe0 into main Oct 2, 2026
2 checks passed
@twistedmelonman
twistedmelonman deleted the claude/fix-node-floor-matrix branch October 2, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant